import 'dart:typed_data';
import 'package:smart_usb_android/smart_usb_android.dart';
import 'package:xsdk_flutter/xsdk/framework/base/xsdk_function.dart';
import 'package:xsdk_flutter/xsdk/framework/bean/x_bean_device.dart';
import 'package:xsdk_flutter/xsdk/operation/x_constant_temp.dart';
import 'package:xsdk_flutter/xsdk/utils/queue/x_bean_queue_message.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_flutter.dart';
import 'package:xsdk_flutter/xsdk/utils/json/x_utils_json.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_log.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_share_preferences.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_string.dart';




/*
usb串口通信(usb/type-c连接硬件)
quick_usb依赖库太旧,编译错误: https://pub.flutter-io.cn/packages/quick_usb
smart_usb实测windows编译出错: https://pub-web.flutter-io.cn/packages/smart_usb
//仅支持android,实测只支持单台usb设备连接, 改用xsdk_flutter_plugin的替代
smart_usb_android: https://pub-web.flutter-io.cn/packages/smart_usb_android
dependencies:
  smart_usb_android: ^1.0.0

import 'package:smart_usb_android/smart_usb_android.dart';


windows:
https://pub-web.flutter-io.cn/packages/usb_esc_printer_windows
https://pub-web.flutter-io.cn/packages/windows_usb_printer


在android清单文件中添加:
<intent-filter>
		<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
	</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
		android:resource="@xml/device_filter" />
注意:这里已使用xsdk_android的XActivity_AutoGetUSBDevicePermission_FlutterXSDKPlugin自动授权

注意: 每次插入自动获取授权和申请授权


 */
abstract class XUsbUtils{

  static bool isReceiveMsg=false;

  //记录设备
  static final Set<XBaseDevice> usbDeviceList={};

  /*
  1.初始化 ok(注意:不能在app中初始化,因为sp初始化没完成,导致获取设备记录为空)
  注意:
  1.1.如果使用多用户保存:
  则需要登录后更新用户组:XSharePreferencesUtils.saveString(XConstants.SP_UserGroup,XXX);
  然后再初始化;切换用户或company时,则需要重新初始化
  1.2.如果不启用多用户,则可在欢迎界面初始化;
   */
  static void init() async{

    if(!XFlutterUtils.isAndroid()){
      XLogUtils.printLog('---非 Android平台,不支持此USB库!');
      return;
    }

    usbDeviceList.clear();

    //1.连接设备
    String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
    String connectDeviceJson=XSharePreferencesUtils.getString('$userGroup${XConstants.SP_UsbDevicesList}');

    if(!XStringUtils.isEmpty(connectDeviceJson)){
      List<dynamic> list=XJsonUtils.json2List(connectDeviceJson);
      for(dynamic item in list){
        usbDeviceList.add(XBaseDevice.fromJson(item));
      }
    }

    XLogUtils.printLog('---设备usb记录数=${usbDeviceList.length}');

    await SmartUsbAndroid.init();
    //只在linux上有效,分离内置驱动,其他平台无效
    await SmartUsbAndroid.setAutoDetachKernelDriver(true);
  }

  //2.退出
  static void exit() async{
    try{

      if(!XFlutterUtils.isAndroid()){
        return;
      }

      isReceiveMsg=false;
      await SmartUsbAndroid.closeDevice();
      await SmartUsbAndroid.exit();

    }catch(e){
      //
    }

  }

  //3.搜索usb设备
  static void scanUsbDevices(
      {
        required XFunctionNotifyScanFinish<UsbDeviceDescription> notifyScanFinish,
      }
      ){

    try{

      // List<UsbDevice> deviceList = await SmartUsbAndroid.getDeviceList();
      // XLogUtils.printLog('---deviceList= ${deviceList.length}');
      // for(UsbDevice item in deviceList){
      //   XLogUtils.printLog('---usbDevice= ${item.identifier}, ${item.toString()}');
      // }

      // List<UsbDeviceDescription> descriptions = await SmartUsb.getDevicesWithDescription();
      // XLogUtils.printLog('---descriptions= ${descriptions.length}');
      // for(UsbDeviceDescription item in descriptions){
      //   XLogUtils.printLog('---usbDeviceDescription= ${item.toString()}');
      // }

      if(!XFlutterUtils.isAndroid()){
        XLogUtils.printLog('---非 Android平台,不支持此USB库!');
        return;
      }


      SmartUsbAndroid.getDevicesWithDescription(requestPermission: false)
          .then(
              (List<UsbDeviceDescription> descriptions){

            XLogUtils.printLog('---android扫描usb设备数量 = ${descriptions.length}');
            for(UsbDeviceDescription usbDeviceDescription in descriptions){
              //设备名称: usbDeviceDescription.product
              //设备品牌: usbDeviceDescription.manufacturer
              //设备序列号(注意:需要获得授权申请,否则返回null): usbDeviceDescription.serialNumber
              //usb路径: usbDeviceDescription.device.identifier
              XLogUtils.printLog('---android usbDeviceDescription= ${usbDeviceDescription.toString()}');
              //UsbDevice device=usbDeviceDescription.device;
            }

            notifyScanFinish(descriptions);

          }
      );


    }catch(e){
      XLogUtils.printLog('e: $e');
    }

  }

  /*

  //点击usb设备列表item
onPress:(){

  //判断item是否授权
  XUsbUtils.hasPermission(device).then((bool hasPermission){
    if(hasPermission){
      //已授权,
      //点击选中设备待添加记录...
      setState((){
        currentSelectIndex= position;
      });

    }else{
      //未授权,不处理提示未授权即可,注意:实测不能用XUsbUtils.requestPermission(device)手动授权,因为api存在bug,返回空指针报错崩溃
      toast('请重新插入usb设备确认授权申请');
  }).onError((error,stackTrace){
      //实测: 重新插入usb设备,旧扫描结果item点击报错,则这里可利用重新扫描设备更新设备列表
      currentSelectIndex=-1;
      updateData();
  });

}
   */
  //4.判断设备是否已授权
  static Future<bool> hasPermission(UsbDevice usbDevice) async{
    bool hasPermission = await SmartUsbAndroid.hasPermission(usbDevice);
    return hasPermission;
  }

  //5.申请授权,实测:空指针报错崩溃,使用重新插入自动获得授权申请替代
  // static Future<bool> requestPermission(UsbDevice usbDevice) async{
  //   var hasPermission = await SmartUsbAndroid.requestPermission(usbDevice);
  //   return hasPermission;
  // }


  //6.添加设备记录(确保已获得授权的设备),场景:在扫描列表中选中添加
  static bool addNoteUsbDevice(UsbDeviceDescription usbDeviceDescription,String customType){
    XBaseDevice usbDevice=XBaseDevice();
    usbDevice.deviceName=usbDeviceDescription.product;
    usbDevice.deviceUUID=_getUsbDeviceUUID(usbDeviceDescription);
    usbDevice.customType=customType;

    if(!usbDeviceList.contains(usbDevice)){
      usbDeviceList.add(usbDevice);

      String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
      XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbDevicesList}',XJsonUtils.obj2Json(usbDeviceList));

      return true;
    }else{
      XLogUtils.printLog('已存在设备记录');
    }

    return false;
  }

  //获得设备唯一id,(获得授权,否则usbDeviceDescription.serialNumber为空)
  static String _getUsbDeviceUUID(UsbDeviceDescription usbDeviceDescription){
    return '${usbDeviceDescription.manufacturer},${usbDeviceDescription.product},${usbDeviceDescription.serialNumber},${usbDeviceDescription.device.productId},${usbDeviceDescription.device.vendorId}';
  }

  //7.更新记录设备
  static bool updateNoteUsbDevice(XBaseDevice device){

    for(XBaseDevice deviceItem in usbDeviceList){
      if(deviceItem==device){
        deviceItem.deviceName=device.deviceName;
        deviceItem.nickName=device.nickName;
        deviceItem.brand=device.brand;
        deviceItem.isConnected=device.isConnected;
        deviceItem.isUserSelect=device.isUserSelect;
        deviceItem.isEnable=device.isEnable;
        deviceItem.customType=device.customType;
        deviceItem.isGBK=device.isGBK;
        deviceItem.isSocketShortConnect=device.isSocketShortConnect;
        deviceItem.isMTULongWrite=device.isMTULongWrite;
        deviceItem.isReceiveDeviceMsg=device.isReceiveDeviceMsg;

        deviceItem.scenes =device.scenes;
        deviceItem.printerPagerSize=device.printerPagerSize;
        deviceItem.serialNumber=device.serialNumber;

        deviceItem.printCommandType=device.printCommandType;
        deviceItem.printTypeName=device.printTypeName;
        deviceItem.printerDPI=device.printerDPI;
        deviceItem.printerLabelSizeWidth=device.printerLabelSizeWidth;
        deviceItem.printerLabelSizeHeight=device.printerLabelSizeHeight;

        String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
        XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbDevicesList}',XJsonUtils.obj2Json(usbDeviceList));

        return true;
      }
    }

    return false;

  }
  //8.1.删除记录设备
  static void removeNoteUsbDevice(XBaseDevice device){

    usbDeviceList.remove(device);

    String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
    XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbDevicesList}',XJsonUtils.obj2Json(usbDeviceList));

  }

  //8.2.删除设备by customType
  static void removeNoteUsbDeviceByType(String deviceCustomType){
    //断开和删除连接, 客户端(适用多个)
    usbDeviceList.removeWhere((XBaseDevice device){
      if(deviceCustomType==device.customType){
        return true;
      }else{
        return false;
      }
    });

    //更新保存
    String userGroup=XSharePreferencesUtils.getString(XConstants.SP_UserGroup);//多用户保存
    XSharePreferencesUtils.saveString('$userGroup${XConstants.SP_UsbDevicesList}',XJsonUtils.obj2Json(usbDeviceList));

  }


  //8.发送消息(用于测试打印),由于该api只支持1台设备连接,则每次发送消息都需要重连设备
  static Future<bool> sendMessage_test(XBaseDevice noteUsbDevice,String text) async{


    //扫描每次确保存在usb连接
    List<UsbDeviceDescription> scanResult= await SmartUsbAndroid.getDevicesWithDescription(requestPermission: false);

    for(UsbDeviceDescription usbDeviceDescription in scanResult){
      UsbDevice usbDevice=usbDeviceDescription.device;
      bool hasPermission = await SmartUsbAndroid.hasPermission(usbDevice);
      if(hasPermission){
        String deviceUUID=_getUsbDeviceUUID(usbDeviceDescription);
        //
        if(noteUsbDevice.deviceUUID==deviceUUID){

          bool openDevice = await SmartUsbAndroid.openDevice(usbDevice);

          XLogUtils.printLog('---打开usb设备,openDevice=$openDevice');

          if(openDevice){
            UsbConfiguration configuration = await SmartUsbAndroid.getConfiguration(0);
            //获得接口
            bool claimInterface = await SmartUsbAndroid.claimInterface(configuration.interfaces[0]);
            XLogUtils.printLog("---获得usb设备接口,claimInterface=$claimInterface");

            //实测报错,ArrayList类型错
            //bool isSend = await SmartUsbAndroid.send(data);

            var endpoint = configuration.interfaces[0].endpoints
                .firstWhere((e) => e.direction == UsbEndpoint.DIRECTION_OUT);
            var bulkTransferOut = await SmartUsbAndroid.bulkTransferOut(endpoint, XStringUtils.stringToUint8List_gbk(text));

            XLogUtils.printLog("---发送消息到usb设备, bulkTransferOut=$bulkTransferOut");
            return true;
          }
        }
      }

    }

    return false;

  }


  static Future<bool> sendMessage(XBaseDevice noteUsbDevice,XBaseQueueMessage msg) async{

    if(msg.message_Uint8List==null){
      return false;
    }

    //扫描每次确保存在usb连接
    List<UsbDeviceDescription> scanResult= await SmartUsbAndroid.getDevicesWithDescription(requestPermission: false);

    for(UsbDeviceDescription usbDeviceDescription in scanResult){
      UsbDevice usbDevice=usbDeviceDescription.device;
      bool hasPermission = await SmartUsbAndroid.hasPermission(usbDevice);
      if(hasPermission){
        String deviceUUID=_getUsbDeviceUUID(usbDeviceDescription);
        //
        if(noteUsbDevice.deviceUUID==deviceUUID){

          bool openDevice = await SmartUsbAndroid.openDevice(usbDevice);

          XLogUtils.printLog('---打开usb设备,openDevice=$openDevice');

          if(openDevice){
            UsbConfiguration configuration = await SmartUsbAndroid.getConfiguration(0);
            //获得接口
            bool claimInterface = await SmartUsbAndroid.claimInterface(configuration.interfaces[0]);
            XLogUtils.printLog("---获得usb设备接口,claimInterface=$claimInterface");

            //实测报错,ArrayList类型错
            //bool isSend = await SmartUsbAndroid.send(data);

            var endpoint = configuration.interfaces[0].endpoints
                .firstWhere((e) => e.direction == UsbEndpoint.DIRECTION_OUT);
            var bulkTransferOut = await SmartUsbAndroid.bulkTransferOut(endpoint, Uint8List.fromList(msg.message_Uint8List!));

            XLogUtils.printLog("---发送消息到usb设备, bulkTransferOut=$bulkTransferOut");
            return true;

          }


        }
      }

    }

    return false;

  }



// //连接第1个
// static void connect() async{
//
//   List<UsbDeviceDescription> descriptions = await SmartUsbAndroid.getDevicesWithDescription(requestPermission: false);
//   XLogUtils.printLog('---android descriptions= ${descriptions.length}');
//   for(UsbDeviceDescription item in descriptions){
//     XLogUtils.printLog('---android usbDeviceDescription= ${item.toString()}');
//   }
//
//   if(descriptions.length!=0){
//     UsbDeviceDescription usbDeviceDescription=descriptions.first;
//
//     UsbDevice device=usbDeviceDescription.device;
//
//     if(XFlutterUtils.isAndroid()){
//       bool hasPermission = await SmartUsbAndroid.hasPermission(device);
//       XLogUtils.printLog("---hasPermission=$hasPermission");
//
//       // if(!hasPermission){
//       //   //手动申请USB权限,注意:实测每次重新插入usb都需要重新记录,确认后android会报空指针异常崩溃退出app,需要重新进入app
//       //   hasPermission=await SmartUsb.requestPermission(device);
//       //   XLogUtils.printLog("---requestPermission=$hasPermission");
//       // }
//       //注意:这里已使用xsdk_android的XActivity_AutoGetUSBDevicePermission_FlutterXSDKPlugin,每次重新插入自动授权和自动申请授权,不需要手动授权
//
//     }
//
//     bool openDevice = await SmartUsbAndroid.openDevice(device);
//
//     XLogUtils.printLog("---openDevice=$openDevice");
//
//     if(openDevice){
//       UsbConfiguration configuration = await SmartUsbAndroid.getConfiguration(0);
//       XLogUtils.printLog("---configuration=${configuration.toString()}");
//
//       //获得接口
//       bool claimInterface = await SmartUsbAndroid.claimInterface(configuration.interfaces[0]);
//       XLogUtils.printLog("---claimInterface=$claimInterface");
//
//       //释放接口
//       //var releaseInterface = await SmartUsbAndroid.releaseInterface(configuration.interfaces[0]);
//
//       var endpoint = configuration.interfaces[0].endpoints
//           .firstWhere((e) => e.direction == UsbEndpoint.DIRECTION_IN);
//
//       while(true){
//         Uint8List bulkTransferIn = await SmartUsbAndroid.bulkTransferIn(endpoint, 1024);
//         XLogUtils.printLog("---bulkTransferIn=${XStringUtils.uint8ListToString_gbk(bulkTransferIn)}");
//         //XLogUtils.printLog("---bulkTransferIn=$bulkTransferIn");
//       }
//
//
//       // var data = Uint8List.fromList(utf8.encode(''));
//       // var endpoint = _configuration!.interfaces[0].endpoints
//       //     .firstWhere((e) => e.direction == UsbEndpoint.DIRECTION_OUT);
//       // var bulkTransferOut =
//       // await SmartUsb.bulkTransferOut(endpoint, data);
//
//
//     }
//
//   }
//
// }


}
